package ferp.android.views;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.*;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.Html;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.style.DynamicDrawableSpan;
import android.text.style.ImageSpan;
import android.util.AttributeSet;
import android.widget.TextView;
import ferp.android.GUI;
import ferp.android.managers.DeckManager;
import ferp.core.card.Card;

/**
 * User: igorgok
 * Date: 12/05/2015 11:34
 */
public class EnhancedTextView extends TextView
{
  public EnhancedTextView(Context context)
  {
    super(context);
  }

  public EnhancedTextView(Context context, AttributeSet attrs)
  {
    super(context, attrs);
  }

  public EnhancedTextView(Context context, AttributeSet attrs, int defStyle)
  {
    super(context, attrs, defStyle);
  }

  public void setText(String text)
  {
    SpannableStringBuilder sb = new SpannableStringBuilder(Html.fromHtml(text));
    State state = State.IDLE;
    int start = 0;

    getPaint().getTextBounds("6", 0, 1, bounds);

    for (int i = 0; i < sb.length(); ++i)
    {
      char c = sb.charAt(i);

      switch (state)
      {
        case IDLE:
          switch (c)
          {
            case '0':
              start = i;
              state = State.SUIT;

              break;

            case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
              start = i;

              if (i + 1 < sb.length() && sb.charAt(i + 1) == '0')
                ++i;

              state = State.BID;

              break;

            case 's': case 'c': case 'd': case 'h': case 'n':
              start = i;
              state = State.CARD;

              break;

            case '{':
              start = i;
              state = State.IMAGE;

              break;
          }

          break;

        case SUIT:
          if ("scdhn".indexOf(c) != -1)
            sb.setSpan(new SuitSpan(c, bounds.height()), start, i + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

          state = State.IDLE;

          break;

        case BID:
          if ("scdhn".indexOf(c) != -1)
            sb.setSpan(new BidSpan(sb.subSequence(start, i).toString(), c, bounds.height(), getPaint()), start, i + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

          state = State.IDLE;

          break;

        case CARD:
          if ("AKQJ19876ТКДВ".indexOf(c) != -1)
          {
            if (i + 1 < sb.length() && sb.charAt(i + 1) == '0')
              ++i;

            sb.setSpan(new CardSpan(sb.subSequence(start + 1, i + 1).toString(), sb.charAt(start), bounds.height(), getPaint()), start, i + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
          }

          state = State.IDLE;

          break;

        case IMAGE:
          int end = i;

          for (; end < sb.length(); ++end)
            if (sb.charAt(end) == '}')
            {
              String name = sb.subSequence(start + 1, end).toString();
              Resources r = getContext().getResources();
              int id = r.getIdentifier(name, "drawable", getContext().getPackageName());
              Drawable d = r.getDrawable(id);

              if (d != null)
              {
                // limit the dimensions
                d.setBounds(0, 0, bounds.height(), bounds.height());
                // create image span to cover the text with the image name with the real image
                sb.setSpan(new ImageSpan(d, ImageSpan.ALIGN_BASELINE), start, end + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

                i = end;

                break;
              }
            }

          state = State.IDLE;

          break;
      }
    }

    super.setText(sb);
  }

  static enum State {IDLE, SUIT, BID, CARD, IMAGE};
  // padding in dp
  static int PADDING = 2;
  static int CORNER_RADIUS = 2;

  private final Rect bounds = new Rect();

/*
  private void putSuitImage(SpannableStringBuilder sb, char c, int from, int to, int height)
  {
    Card.Suit suit = Card.Suit.byShortName("" + c);

    if (suit != null)
    {
      String name = "suit_" + c + "_e";
      Resources r = getContext().getResources();
      int id = r.getIdentifier(name, "drawable", getContext().getPackageName());
      Drawable d = r.getDrawable(id);

      if (d != null)
      {
        // limit the dimensions
        d.setBounds(0, 0, height, height);
        // create image span to cover the text with the image name with the real image
        sb.setSpan(new ImageSpan(d, ImageSpan.ALIGN_BASELINE), from, to, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
      }
    }
  }
*/

  class SuitSpan extends DynamicDrawableSpan
  {
    SuitSpan(char suit, int height)
    {
      super(ALIGN_BASELINE);

      int padding = GUI.dp2px(getResources(), PADDING);

      height += padding * 2;

      Card.Suit s = Card.Suit.byShortName("" + suit);
      Drawable sd = DeckManager.instance(getContext()).getTutorialSuitImage(s);
      Bitmap b = Bitmap.createBitmap(height, height, Bitmap.Config.ARGB_8888);
      Canvas c = new Canvas(b);
      int center = height / 2;

      anti.setColor(0x88FFFFFF);
      //c.drawRoundRect(new RectF(0, 0, height, height), 3, 3, anti);
      c.drawCircle(center, center, center, anti);

      sd.setBounds(padding, padding, height - padding, height - padding);
      sd.draw(c);

      this.drawable = new BitmapDrawable(b);
      this.drawable.setBounds(0, 0, height, height);
    }

    @Override
    public Drawable getDrawable() {return drawable;}

    final Drawable drawable;
    final Paint anti = new Paint(Paint.ANTI_ALIAS_FLAG);
  }

  class CardSpan extends DynamicDrawableSpan
  {
    CardSpan(String rank, char suit, int height, TextPaint tp)
    {
      super(ALIGN_BASELINE);

      int padding = GUI.dp2px(getResources(), PADDING);
      int radius = GUI.dp2px(getResources(), CORNER_RADIUS);
      Card.Suit s = Card.Suit.byShortName("" + suit);
      Drawable sd = DeckManager.instance(getContext()).getTutorialSuitImage(s);
      TextPaint paint = new TextPaint(tp);

      paint.setColor(GUI.getSuitColor(s));
      paint.setFakeBoldText(true);
      paint.setAntiAlias(true);
      paint.setTypeface(GUI.Font.BOLD);

      height += padding * 2;

      int rw = Math.round(paint.measureText(rank));
      Bitmap b = Bitmap.createBitmap(rw + height, height, Bitmap.Config.ARGB_8888);
      Canvas c = new Canvas(b);

      anti.setColor(0x88FFFFFF);
      c.drawRoundRect(new RectF(0, 0, rw + height, height), radius, radius, anti);

      c.drawText(rank, height - padding, height - padding, paint);
      sd.setBounds(padding, padding, height - padding, height - padding);
      sd.draw(c);

      this.drawable = new BitmapDrawable(b);
      this.drawable.setBounds(0, 0, rw + height, height);
    }

    @Override
    public Drawable getDrawable() {return drawable;}

    final Drawable drawable;
    final Paint anti = new Paint(Paint.ANTI_ALIAS_FLAG);
  }

  class BidSpan extends DynamicDrawableSpan
  {
    BidSpan(String tricks, char suit, int height, TextPaint tp)
    {
      super(ALIGN_BASELINE);

      int padding = GUI.dp2px(getResources(), PADDING);
      int radius = GUI.dp2px(getResources(), CORNER_RADIUS);
      Card.Suit s = Card.Suit.byShortName("" + suit);
      Drawable sd = DeckManager.instance(getContext()).getTutorialSuitImage(s);
      TextPaint paint = new TextPaint(tp);

      paint.setColor(GUI.getSuitColor(s));
      paint.setFakeBoldText(true);
      paint.setAntiAlias(true);
      paint.setTypeface(GUI.Font.BOLD);

      height += padding * 2;

      int tw = Math.round(paint.measureText(tricks));
      Bitmap b = Bitmap.createBitmap(tw + height, height, Bitmap.Config.ARGB_8888);
      Canvas c = new Canvas(b);

      anti.setColor(0x88FFFFFF);
      c.drawRoundRect(new RectF(0, 0, tw + height, height), radius, radius, anti);

      c.drawText(tricks, padding, height - padding, paint);
      sd.setBounds(tw + padding, padding, tw + height - padding, height - padding);
      sd.draw(c);

      this.drawable = new BitmapDrawable(b);
      this.drawable.setBounds(0, 0, tw + height, height);
    }

    @Override
    public Drawable getDrawable() {return drawable;}

    final Drawable drawable;
    final Paint anti = new Paint(Paint.ANTI_ALIAS_FLAG);
  }
}
